package utils;

import java.util.ArrayList;
import java.util.List;

/**
 * A degree vector is a vector of any length holding the number of edges connecting a given vertex to 
 * the block <i>i</i> of some partition.
 * @author Alex Dusenbery 
 * @version 0.1
 *
 */
@SuppressWarnings("rawtypes")
public class DegreeVector implements Comparable{

	private List<Double> vector;
	private double sum;
	
	/**
	 * Creates a new, empty degree vector.
	 */
	public DegreeVector() {
		vector = new ArrayList<Double>();
		sum = 0;
	}
	
	/**
	 * Creates a new degree vector from an array of degrees (as doubles).
	 * A degree vector is a vector of any length holding the number of edges connecting a given vertex to 
	 * the block <i>i</i> of some partition.
	 * @param degree The array to turn into a degree vector.
	 */
	public DegreeVector (Double[] degree) {
		vector = new ArrayList<Double>();
		sum = 0;
		for(Double d : degree) { 
			vector.add(d);
			sum += (Double) d;
		}
	}

	/**
	 * @return the vector
	 */
	public List<Double> getVector() {
		return vector;
	}
	
	/**
	 * Gets the value at a given index of the vector.
	 * @param index
	 * @return
	 */
	public Double getEntry(int index) {
		return vector.get(index);
	}
	
	/**
	 * Sets the value at a given index of the vector.
	 * @param index
	 * @param value
	 */
	public void setEntry(int index, Double value) {
		vector.set(index, value);
	}

	/**
	 * Returns the sum of all components of the vector.
	 * @return the sum
	 */
	public double getSum() {
		sum = 0;
		for(Double d : vector)
			sum += (Double) d;
		return sum;
	}

	@Override
	public int compareTo(Object that) {
		Double thisSum = this.getSum();
		Double thatsum = ((DegreeVector)that).getSum();
		return thisSum.compareTo(thatsum);
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(sum);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		result = prime * result + ((vector == null) ? 0 : vector.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof DegreeVector)) {
			return false;
		}
		DegreeVector other = (DegreeVector) obj;
		if (Double.doubleToLongBits(sum) != Double.doubleToLongBits(other.sum)) {
			return false;
		}
		if (vector == null) {
			if (other.vector != null) {
				return false;
			}
		} else if (!vector.equals(other.vector)) {
			return false;
		}
		return true;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("[{");
		for(Double d : this.vector)
			sb.append(d).append(",");
		sb.deleteCharAt(sb.lastIndexOf(","));
		sb.append("}");
		sb.append("sum=").append(this.getSum());
		sb.append("]");
		return sb.toString();
	}
}
